import { apiMenu, apiList } from '../utils/utils.js';
import KS3 from 'ks3-js-sdk';
import { Button, Input, Menu, MenuItem, Form, FormItem, Tooltip, Tab, Tabs, Table, TableColumn, Dialog, Icon, Upload, Pagination, Switch as KSwitch, Progress, Spin, Message } from '@king-design/vue-legacy'
export default {
    name: 'Layout',
    components: { Button, Input, Menu, MenuItem, Form, FormItem, Tooltip, Tab, Tabs, Table, TableColumn, Dialog, Icon, Upload, Pagination, KSwitch, Progress, Spin },
    data() {
        return {
            ks3: '',                 // ks3实例化对象
            searchApi: '',           // 搜索框中的内容
            selectedApiName: '',     // 选中的api名称
            selectedApi: {},         // 选择api的全部信息
            result: {},              // api调用结果
            must: false,             // 只显示必填参数
            rightTab: 'result',      // 右侧tab栏的值
            config: {},              // 初始配置
            configForm: {},          // 配置表单
            apiList: [],             // api列表
            apiMenu: [],             // 左侧api菜单
            recordList: [],          // api调用历史记录
            recordPageList: [],          // api调用历史记录
            fileList: [],            // 上传的文件列表
            resultInfo: {},          // 响应结果信息
            responseTab: 'headers',  // 响应的tab栏
            currentPage: 1,          // 当前展示分页
            limitPage: 10,           // 每页的数据条数
            percent: 0,              // 上传或下载进度
            resultState: 'noResult', // 调用状态
            showConfigDialog: false, // 是否展示全局弹窗
            timer: null,             // 进度条定时器
            xhr: null,               // 正在执行的xhr实例
            abortMulti: {}           // 取消分块上传的信息
        }
    },
    mounted() {
        // 优先使用localStorage中的数据
        if (localStorage.getItem('config')) {
            this.config = JSON.parse(localStorage.getItem('config'));
            this.ks3 = new KS3(this.config);
        } else {
            // 如果没有则尝试读取默认配置
            this.ks3 = new KS3();
            let { bucket, region, AK, SK, securityToken } = this.ks3.config;
            this.config = {
                bucket, region, AK, SK, securityToken
            }
        }
        //初始化数据
        this.apiList = apiList;
        this.apiMenu = apiMenu;
        this.selectedApiName = 'listObjects';
        this.configForm = { ...this.config };
        this.selectedApi = this.apiList[0];
        this.resultInfo = {
            resultFlag: true,  // 调试结果成功或者失败的标志位
            apiRunStart: 0,    // api执行的开始时间
            apiRunEnd: 0,      // api执行的结束时间
            apiRunTime: 0,     // api执行耗时
            resultCode: '无'   // 响应码
        };
        this.abortMulti = {
            uploadId: '',
            state: 'noTask',
            key: ''
        }
    },
    watch: {
        // 选中的api名称
        selectedApiName(newValue, oldValue) {
            // 改变调用状态
            this.resultState = 'noResult';
            // 清空表单
            this.resetParamsForm();
            // 如果有请求在执行，则取消
            if (this.xhr) {
                this.xhr.abort();
                this.xhr = null;
                Message.warning('调用已取消!', 1000);
            }
            if (oldValue === 'uploadMultiPart' && this.abortMulti.state === 'running' && this.abortMulti.uploadId) {
                this.ks3.abortMultipartUpload({
                    key: this.abortMulti.key,
                    uploadId: this.abortMulti.uploadId
                }).then(res => {
                    this.abortMulti.state = 'cancel';
                    console.log(res)
                })
                Message.warning('调用已取消!', 1000);
            }
            this.apiList.forEach(item => {
                if (item.name === newValue) {
                    this.selectedApi = item;
                    this.result = {};
                    return;
                }
            });
        },
        // 右侧的tab栏的名称
        rightTab(newValue) {
            if (newValue === 'config') {
                this.configForm = { ...this.config };
            }
        }
    },
    computed: {
        // 展示的api列表
        showApiList() {
            let list = [];
            this.apiMenu.forEach(item => {
                let arr = item.list.filter(api => api.indexOf(this.searchApi) !== -1);
                list.push({
                    type: item.type,
                    list: arr
                })
            })
            return list;
        },
        // 是否有需要填写的参数
        needParams() {
            let paramsNum = [];
            if (this.selectedApi.params) {
                paramsNum = this.selectedApi.params.filter(item => {
                    return (this.must ? item.required : true) && item.show;
                })
            }
            return paramsNum.length > 0;
        },
        // 响应头
        responseHeaders() {
            let headers = JSON.stringify(this.result.headers, null, 2);
            return headers ? headers : '{}';
        },
        // 响应体
        responseBody() {
            let body = JSON.stringify(this.result.body, null, 2);
            return body ? body : '{}';
        },
        // 错误信息
        responseError() {
            let error = JSON.stringify(this.result.error, null, 2);
            return error ? error : '{}';
        },
        // 返回的url
        responseUrl() {
            if (this.selectedApiName === 'getObjectUrl') {
                // 执行了getObjectUrl
                return this.result;
            } else if (this.selectedApiName === 'putObjectByPresignedUrl') {
                // 执行了putObjectByPresignedUrl
                return this.result;
            }
        }
    },
    methods: {
        // 输出结果
        logResult(res) {
            // 改变调用状态
            this.resultState = 'result';
            // 切换tab栏
            this.responseTab = 'headers';
            // 判断调用成功或失败
            if (res.error) {
                this.resultInfo.resultFlag = 'fail';
            } else {
                if (this.selectedApiName === 'getObjectUrl' || this.selectedApiName === 'putObjectByPresignedUrl') {
                    this.resultInfo.resultFlag = 'url';
                    this.responseTab = 'url';
                } else {
                    this.resultInfo.resultFlag = 'success';
                }
            }
            console.log('res', res);
            // xhr 置空
            this.xhr = null;
            // 计时结束
            this.resultInfo.apiRunEnd = Date.now();
            // 计算api执行耗时
            this.resultInfo.apiRunTime = this.resultInfo.apiRunEnd - this.resultInfo.apiRunStart;
            // 判断调用是否成功
            if (res.statusCode !== null && res.statusCode !== undefined) {
                this.resultInfo.resultCode = res.statusCode;
            }
            // 添加一条记录
            this.recordList.unshift({
                time: this.getDay(),
                name: this.selectedApi.name,
                code: res.statusCode || '无',
                message: res.statusMessage || '无'
            });
            // 结果赋值
            this.result = res;
            this.recordPageList = this.recordList.slice((this.currentPage - 1) * this.limitPage, this.currentPage * this.limitPage);
        },
        // 保存全局配置
        async submitConfig() {
            if (await this.$refs.configForm.validate()) {
                this.config = { ... this.configForm };
                console.log('config:', this.config);
                // 存储在本地
                localStorage.setItem('config', JSON.stringify(this.config));
                // 关闭弹窗
                this.$refs.configDialog.close();
                this.ks3 = new KS3(this.config);
                Message.success('修改配置成功!', 1000);
            }
        },
        // 调用api
        async runApi() {
            if (await this.$refs.paramsForm.validate()) {
                if (await this.$refs.configForm.validate()) {
                    // 正在上传
                    if (this.resultState === 'uploading') {
                        Message.warning('文件正在上传中，请不要重复调用!', 1000);
                        return;
                    }
                    // 正在执行
                    if (this.resultState === 'loading') {
                        Message.warning('正在执行中，请稍后!', 1000);
                        return;
                    }
                    // 计时开始
                    this.resultInfo.apiRunStart = Date.now();
                    // 进度清零
                    this.percent = 0;
                    // 判断加载的动画
                    if (this.selectedApiName === 'putObject' || this.selectedApiName === 'uploadMultiPart') {
                        this.resultState = 'uploading';
                    } else {
                        this.resultState = 'loading';
                    }
                    // 调用对应的方法
                    this.xhr = this[this.selectedApiName]();
                    // 显示结果
                    this.rightTab = 'result';
                } else {
                    this.$refs.configDialog.show();
                }
            }
        },
        // 取消调用
        abortApi() {
            // 取消调用
            if (this.xhr) {
                this.xhr.abort();
                this.xhr = null;
                Message.success('调用已取消!', 1000);
            }
            if (this.selectedApiName === 'uploadMultiPart' && this.abortMulti.state === 'running' && this.abortMulti.uploadId) {
                this.ks3.abortMultipartUpload({
                    key: this.abortMulti.key,
                    uploadId: this.abortMulti.uploadId
                }, (err, data) => {
                    this.abortMulti.state = 'cancel';
                    console.log(err, data);
                })
                Message.success('调用已取消!', 1000);
            }
            // 改变tab栏
            this.resultState = 'noResult'
        },
        // 清空表单
        resetParamsForm() {
            for (let key in this.selectedApi.paramsForm) {
                this.selectedApi.paramsForm[key] = '';
            }
            this.$refs.paramsForm.reset();
            this.fileList.pop();
        },
        // 上传之前
        beforeUpload(file, files) {
            if (files.length > 0) {
                this.fileList.pop()
            }
            this.fileList.push(file);
            this.selectedApi.paramsForm.file = file.raw;
            this.selectedApi.paramsForm.key = this.selectedApi.paramsForm.file.name;
            return false;
        },
        // 删除文件之前
        beforeRemove() {
            this.fileList.pop();
            this.selectedApi.paramsForm.file = '';
        },
        // 改变历史记录表格页码
        changePage(obj) {
            this.currentPage = obj.value;
            this.limitPage = obj.limit;
            this.recordPageList = this.recordList.slice((this.currentPage - 1) * this.limitPage, this.currentPage * this.limitPage);
        },

        // 获取当前时间
        getDay() {
            let date = new Date();
            // yyyy-MM-dd hh:mm:ss
            let Y = date.getFullYear() + '-';
            let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
            let D = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() + ' ';
            let h = date.getHours() < 10 ? '0' + date.getHours() + ':' : date.getHours() + ':';
            let m = date.getMinutes() < 10 ? '0' + date.getMinutes() + ':' : date.getMinutes() + ':';
            let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
            return Y + M + D + ' ' + h + m + s;
        },

        // 获取对象列表
        listObjects() {
            return this.ks3.listObjects(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            });
        },

        // 获取对象信息
        headObject() {
            return this.ks3.headObject(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 获取对象
        getObject() {
            return this.ks3.getObject(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 获取对象的Url
        getObjectUrl() {
            this.ks3.getObjectUrl(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 生成上传外链上传
        putObjectByPresignedUrl() {
            this.ks3.putObjectByPresignedUrl(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 删除指定对象
        delObject() {
            return this.ks3.delObject(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 添加对象
        putObject() {
            this.selectedApi.paramsForm.progress = (e) => {
                this.percent = Number.parseInt(e.percent * 100);
            }
            return this.ks3.putObject(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 获取对象的ACL
        getObjectAcl() {
            return this.ks3.getObjectAcl(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 设置对象的ACL
        putObjectAcl() {
            return this.ks3.putObjectAcl(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // post上传对象
        postObject() {
            let formData = new FormData();
            formData.append('key', this.selectedApi.paramsForm.key);
            formData.append('file', this.selectedApi.paramsForm.file);
            let policy = {
                expiration: new Date(Date.now() + 900 * 1000).toISOString(),
                conditions: [
                    ["eq", "$bucket", this.selectedApi.paramsForm.bucket || this.ks3.config.bucket],
                    ['eq', '$key', this.selectedApi.paramsForm.key]
                ]
            }
            if(this.selectedApi.paramsForm.acl) {
                formData.append('acl', this.selectedApi.paramsForm.acl);
                policy.conditions.push(['eq', '$acl', this.selectedApi.paramsForm.acl])
            }
            formData.append('policy', JSON.stringify(policy));
            return this.ks3.postObject({
                formData
            }).then(res => {
                this.logResult(res);
            })
        },

        // 分块上传
        uploadMultiPart() {
            // 设置状态为进行中
            this.abortMulti.state = 'running';
            this.abortMulti.key = this.selectedApi.paramsForm.key;
            this.selectedApi.paramsForm.progress = (e) => {
                this.percent = Number.parseInt(e.percent * 100);
                this.abortMulti.uploadId = e.uploadId;
            }
            return this.ks3.uploadMultiPart(this.selectedApi.paramsForm, (res) => {
                // 如果任务没有被取消，则输出结果
                if (this.abortMulti.state !== 'cancel') {
                    this.logResult(res);
                }
                // 改变状态为无任务
                this.abortMulti.state = 'noTask';
                // 置空uploadId
                this.abortMulti.uploadId = '';
            })
        },

        // 查看已上传的分块
        listParts() {
            return this.ks3.listParts(this.selectedApi.paramsForm).then( res => {
                this.logResult(res);
            })
        },

        // 取消已上传块
        abortMultipartUpload() {
            return this.ks3.abortMultipartUpload(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 查询正在进行的分块上传
        listMultipartUploads() {
            return this.ks3.listMultipartUploads(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 查询object下的正在上传的分块
        getObjectPartUploads() {
            return this.ks3.getObjectPartUploads(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 分块复制文件
        uploadPartCopy() {
            return this.ks3.uploadPartCopy(this.selectedApi.paramsForm,(res) => {
                this.logResult(res);
            })
        },

        // 复制小文件
        putObjectCopy() {
            return this.ks3.putObjectCopy(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 解冻指定对象
        restoreObject() {
            return this.ks3.restoreObject(this.selectedApi.paramsForm).then(res => {
                this.logResult(res);
            })
        },

        // 修改对象的存储类型
        modifyStorageClass() {
            return this.ks3.modifyStorageClass(this.selectedApi.paramsForm,).then(res => {
                this.logResult(res);
            })
        },
    }
}